/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aseclipse.osgi.loader
{
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    
    import mx.logging.ILogger;
    import mx.logging.Log;
    
    import org.aseclipse.core.runtime.PluginConstants;
    
    public class ResourceLoader
    {
        private static var log_:ILogger =  Log.getLogger("ResourceLoader");
        private var plugin:String;
        private var url:String;
        private var callback:Function;
        private var faultCall:Function;
        public function ResourceLoader()
        {
        }
        /*********
        * Loading plugin.xml from server side.
        * @param pluginId
        * @param pattern 
        *     OSGiConstants.PATTERN_PLUGIN 
        *         loading a single plugin.xml for bundle with id "pluginId"
        *     OSGiConstants.PATTERN_EXTENDER
        *         loading all extenders plugin.xml for pluginId
        *         For example, A and B extends C; then load A and B's plugin.xml at invocation "loadPlugin('C', true)"
        * @param fun successful callback
        * @param fail failure callback
        */ 
        public function loadPlugin(pluginId:String, pattern:String, fun:Function, fail:Function):void {
            plugin = pluginId;
            callback = fun;
            faultCall = fail;
            if(pattern == BundleConstants.PATTERN_PLUGIN) {
                this.url = BundleConstants.getResourceURL(pluginId, PluginConstants.PLUGIN_XML);
            } else if(pattern == BundleConstants.PATTERN_EXTENDER) {
                this.url = BundleConstants.getExtendersURL(pluginId);
            } else {
                throw new Error("Unidentified pattern: " + pattern);
            }
            trace("[loadPlugin]: " + url);
            var request:URLRequest = new URLRequest(url);
            var load:URLLoader = new URLLoader();
            load.addEventListener(Event.COMPLETE, completeLoadHandler);
            load.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            load.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
            load.load(request);
        }
        
        public function loadExtenderPlugins(pluginId:String, fun:Function, fail:Function):void {
            callback = fun;
            faultCall = fail;
            this.url = BundleConstants.getResourceURL(pluginId, PluginConstants.PLUGIN_XML); 
            trace("[loadExtenderPlugins]: " + url);
            var request:URLRequest = new URLRequest(url);
            var load:URLLoader = new URLLoader();
            load.addEventListener(Event.COMPLETE, completeLoadHandler);
            load.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            load.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
            load.load(request);
        }
        
        private function completeLoadHandler(event:Event):void {
            var load:URLLoader = event.target as URLLoader;
            load.removeEventListener(Event.COMPLETE, completeLoadHandler);
            var content:String  = String(load.data);
            trace("plugin.xml: " + content);
            var xml:XML;
            try {
                xml = new XML(content);
            } catch(err:Error) {
                log_.error("Load successfully, but data is not xml: " + content + ", " + err.getStackTrace());
            }
            if(callback != null)
                callback.apply(this, [plugin, xml]);
            cleanup();
        }
        
        private function errorHandler(event:IOErrorEvent):void {
            trace("OSGi load fails because of no '"+url+"' " + event.toString());
            var load:URLLoader = event.target as URLLoader;
            load.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            
            if(faultCall != null)
                faultCall.apply(this, [event]);
            cleanup();        
        }
        
        private function onSecurityError(event:SecurityErrorEvent):void {
            trace( "Configuration file (" + url + ") could not be loaded. Error: " +
                     event.toString() );
            var load:URLLoader = event.target as URLLoader;
            load.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);   
            if(faultCall != null)
                faultCall.apply(this, [event]);
            cleanup();           
        }
        
        private function cleanup():void {
            callback = null;
            faultCall = null;
        }
    }
}